{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# NebulaGraph Property Graph Index\n",
    "\n",
    "NebulaGraph is an open-source distributed graph database built for super large-scale graphs with milliseconds of latency.\n",
    "\n",
    "If you already have an existing graph, please skip to the end of this notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install llama-index llama-index-graph-stores-nebula jupyter-nebulagraph"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Docker Setup\n",
    "\n",
    "To launch NebulaGraph locally, first ensure you have docker installed. Then, you can launch the database with the following docker command.\n",
    "\n",
    "```bash\n",
    "mkdir nebula-docker-compose\n",
    "cd nebula-docker-compose\n",
    "curl --output docker-compose.yaml https://raw.githubusercontent.com/vesoft-inc/nebula-docker-compose/master/docker-compose-lite.yaml\n",
    "docker compose up \n",
    "```\n",
    "\n",
    "After this, you are ready to create your first property graph!\n",
    "\n",
    "> Other options/details for deploying NebulaGraph can be found in the [docs](https://docs.nebula-graph.io/):\n",
    ">\n",
    "> - [ad-hoc cluster in Google Colab](https://docs.nebula-graph.io/master/4.deployment-and-installation/2.compile-and-install-nebula-graph/8.deploy-nebula-graph-with-lite/).\n",
    "> - [Docker Desktop Extension](https://docs.nebula-graph.io/master/2.quick-start/1.quick-start-workflow/).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1;3;38;2;47;75;124mConnection Pool Created\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: []\n",
       "Index: []"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# load NebulaGraph Jupyter extension to enable %ngql magic\n",
    "%load_ext ngql\n",
    "# connect to NebulaGraph service\n",
    "%ngql --address 127.0.0.1 --port 9669 --user root --password nebula\n",
    "# create a graph space(think of a Database Instance) named: llamaindex_nebula_property_graph\n",
    "%ngql CREATE SPACE IF NOT EXISTS llamaindex_nebula_property_graph(vid_type=FIXED_STRING(256));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: []\n",
       "Index: []"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# use the graph space, which is similar to \"use database\" in MySQL\n",
    "# The space was created in async way, so we need to wait for a while before using it, retry it if failed\n",
    "%ngql USE llamaindex_nebula_property_graph;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Env Setup\n",
    "\n",
    "We need just a few environment setups to get started."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = \"sk-proj-...\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!mkdir -p 'data/paul_graham/'\n",
    "!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "\n",
    "nest_asyncio.apply()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.core import SimpleDirectoryReader\n",
    "\n",
    "documents = SimpleDirectoryReader(\"./data/paul_graham/\").load_data()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We choose using gpt-4o and local embedding model intfloat/multilingual-e5-large . You can change to what you like, by editing the following lines:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install llama-index-embeddings-huggingface"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.core import Settings\n",
    "from llama_index.llms.openai import OpenAI\n",
    "from llama_index.embeddings.openai import OpenAIEmbedding\n",
    "from llama_index.embeddings.huggingface import HuggingFaceEmbedding\n",
    "\n",
    "Settings.llm = OpenAI(model=\"gpt-4o\", temperature=0.3)\n",
    "Settings.embed_model = HuggingFaceEmbedding(\n",
    "    model_name=\"intfloat/multilingual-e5-large\"\n",
    ")\n",
    "# Settings.embed_model = OpenAIEmbedding(model_name=\"text-embedding-3-small\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Index Construction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Prepare property graph store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.graph_stores.nebula import NebulaPropertyGraphStore\n",
    "\n",
    "graph_store = NebulaPropertyGraphStore(\n",
    "    space=\"llamaindex_nebula_property_graph\", overwrite=True\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And vector store:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.core.vector_stores.simple import SimpleVectorStore\n",
    "\n",
    "vec_store = SimpleVectorStore()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, build the index!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/loganmarkewich/Library/Caches/pypoetry/virtualenvs/llama-index-caVs7DDe-py3.11/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n",
      "Parsing nodes: 100%|██████████| 1/1 [00:00<00:00, 20.96it/s]\n",
      "Extracting paths from text: 100%|██████████| 22/22 [00:19<00:00,  1.15it/s]\n",
      "Extracting implicit paths: 100%|██████████| 22/22 [00:00<00:00, 25253.06it/s]\n",
      "Generating embeddings: 100%|██████████| 1/1 [00:01<00:00,  1.06s/it]\n",
      "Generating embeddings: 100%|██████████| 5/5 [00:02<00:00,  2.50it/s]\n"
     ]
    }
   ],
   "source": [
    "from llama_index.core.indices.property_graph import PropertyGraphIndex\n",
    "from llama_index.core.storage.storage_context import StorageContext\n",
    "from llama_index.llms.openai import OpenAI\n",
    "\n",
    "index = PropertyGraphIndex.from_documents(\n",
    "    documents,\n",
    "    property_graph_store=graph_store,\n",
    "    vector_store=vec_store,\n",
    "    show_progress=True,\n",
    ")\n",
    "\n",
    "index.storage_context.vector_store.persist(\"./data/nebula_vec_store.json\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that the graph is created, we can explore it with [jupyter-nebulagraph](https://github.com/wey-gu/jupyter_nebulagraph)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Chunk__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Entity__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Node__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Props__</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Name\n",
       "0   Chunk__\n",
       "1  Entity__\n",
       "2    Node__\n",
       "3   Props__"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%ngql SHOW TAGS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Relation__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>__meta__node_label__</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>__meta__rel_label__</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   Name\n",
       "0            Relation__\n",
       "1  __meta__node_label__\n",
       "2   __meta__rel_label__"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%ngql SHOW EDGES"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>src</th>\n",
       "      <th>relation</th>\n",
       "      <th>dest</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>We</td>\n",
       "      <td>Charged</td>\n",
       "      <td>$100 a month for a small store</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>We</td>\n",
       "      <td>Charged</td>\n",
       "      <td>$300 a month for a big store</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>We</td>\n",
       "      <td>Got to work</td>\n",
       "      <td>Build software</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>We</td>\n",
       "      <td>Started</td>\n",
       "      <td>Company</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>We</td>\n",
       "      <td>Start</td>\n",
       "      <td>Investment firm</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>We</td>\n",
       "      <td>Opened for business</td>\n",
       "      <td>January 1996</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>We</td>\n",
       "      <td>Had</td>\n",
       "      <td>One that worked</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>We</td>\n",
       "      <td>Decided to try making</td>\n",
       "      <td>Version of store builder</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Growth rate</td>\n",
       "      <td>Takes care of</td>\n",
       "      <td>Absolute number</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Stock</td>\n",
       "      <td>Went up</td>\n",
       "      <td>5x</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>Jessica livingston</td>\n",
       "      <td>In charge of</td>\n",
       "      <td>Marketing at boston investment bank</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>Language</td>\n",
       "      <td>Would be</td>\n",
       "      <td>Dialect of lisp</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>Language</td>\n",
       "      <td>Used</td>\n",
       "      <td>Early version of fortran</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>Arc</td>\n",
       "      <td>Compiled into</td>\n",
       "      <td>Scheme</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>Deal</td>\n",
       "      <td>Became</td>\n",
       "      <td>Model for y combinator's</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   src               relation                                 dest\n",
       "0                   We                Charged       $100 a month for a small store\n",
       "1                   We                Charged         $300 a month for a big store\n",
       "2                   We            Got to work                       Build software\n",
       "3                   We                Started                              Company\n",
       "4                   We                  Start                      Investment firm\n",
       "5                   We    Opened for business                         January 1996\n",
       "6                   We                    Had                      One that worked\n",
       "7                   We  Decided to try making             Version of store builder\n",
       "8          Growth rate          Takes care of                      Absolute number\n",
       "9                Stock                Went up                                   5x\n",
       "10  Jessica livingston           In charge of  Marketing at boston investment bank\n",
       "11            Language               Would be                      Dialect of lisp\n",
       "12            Language                   Used             Early version of fortran\n",
       "13                 Arc          Compiled into                               Scheme\n",
       "14                Deal                 Became             Model for y combinator's"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%ngql MATCH p=(v:Entity__)-[r]->(t:Entity__) RETURN v.Entity__.name AS src, r.label AS relation, t.Entity__.name AS dest LIMIT 15;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>p</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>(\"We\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"4145ba08-a096-4ac1-8f7c-f40642c857cc\"} :Node__{label: \"entity\"} :Entity__{name: \"We\"})-[:Relation__@0{label: \"Charged\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_name: \"paul_graham_essay.txt\", file_type: \"text/plain\", file_size: 75042, _node_type: __NULL__, creation_date: \"2024-05-31\", document_id: __NULL__, last_modified_date: \"2024-05-31\", doc_id: __NULL__, _node_content: __NULL__, ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"}]-&gt;(\"$100 a month for a small store\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"} :Node__{label: \"entity\"} :Entity__{name: \"$100 a month for a small store\"})</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>(\"We\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"4145ba08-a096-4ac1-8f7c-f40642c857cc\"} :Node__{label: \"entity\"} :Entity__{name: \"We\"})-[:Relation__@0{label: \"Charged\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_name: \"paul_graham_essay.txt\", file_type: \"text/plain\", file_size: 75042, _node_type: __NULL__, creation_date: \"2024-05-31\", document_id: __NULL__, last_modified_date: \"2024-05-31\", doc_id: __NULL__, _node_content: __NULL__, ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"}]-&gt;(\"$300 a month for a big store\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"} :Node__{label: \"entity\"} :Entity__{name: \"$300 a month for a big store\"})</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 p\n",
       "0  (\"We\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"4145ba08-a096-4ac1-8f7c-f40642c857cc\"} :Node__{label: \"entity\"} :Entity__{name: \"We\"})-[:Relation__@0{label: \"Charged\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_name: \"paul_graham_essay.txt\", file_type: \"text/plain\", file_size: 75042, _node_type: __NULL__, creation_date: \"2024-05-31\", document_id: __NULL__, last_modified_date: \"2024-05-31\", doc_id: __NULL__, _node_content: __NULL__, ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"}]->(\"$100 a month for a small store\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"} :Node__{label: \"entity\"} :Entity__{name: \"$100 a month for a small store\"})\n",
       "1      (\"We\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"4145ba08-a096-4ac1-8f7c-f40642c857cc\"} :Node__{label: \"entity\"} :Entity__{name: \"We\"})-[:Relation__@0{label: \"Charged\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_name: \"paul_graham_essay.txt\", file_type: \"text/plain\", file_size: 75042, _node_type: __NULL__, creation_date: \"2024-05-31\", document_id: __NULL__, last_modified_date: \"2024-05-31\", doc_id: __NULL__, _node_content: __NULL__, ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"}]->(\"$300 a month for a big store\" :Props__{_node_content: __NULL__, _node_type: __NULL__, creation_date: \"2024-05-31\", doc_id: __NULL__, document_id: __NULL__, file_name: \"paul_graham_essay.txt\", file_path: \"/Users/loganmarkewich/giant_change/llama_index/docs/examples/property_graph/data/paul_graham/paul_graham_essay.txt\", file_size: 75042, file_type: \"text/plain\", last_modified_date: \"2024-05-31\", ref_doc_id: __NULL__, triplet_source_id: \"0faa4540-57bb-4b94-8bc2-46431d980182\"} :Node__{label: \"entity\"} :Entity__{name: \"$300 a month for a big store\"})"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%ngql MATCH p=(v:Entity__)-[r]->(t:Entity__) RETURN p LIMIT 2;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%ng_draw"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Querying and Retrieval"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interleaf -> Got a job at -> I\n",
      "Interleaf -> Crushed -> Moore's law\n",
      "Interleaf -> Was -> Company\n",
      "Interleaf -> Built -> Impressive technology\n",
      "Interleaf -> Added -> Scripting language\n",
      "Interleaf -> Had -> Smart people\n",
      "Interleaf -> Made -> Software for creating documents\n",
      "Viaweb -> Called -> Company\n",
      "Viaweb -> Worked for -> Dan giffin\n",
      "Viaweb -> Was -> Application service provider\n",
      "In viaweb -> Was -> Code editor\n",
      "Viaweb stock -> Was -> Valuable\n",
      "Viaweb logo -> Had -> White v on red circle\n"
     ]
    }
   ],
   "source": [
    "retriever = index.as_retriever(\n",
    "    include_text=False,  # include source text in returned nodes, default True\n",
    ")\n",
    "\n",
    "nodes = retriever.retrieve(\"What happened at Interleaf and Viaweb?\")\n",
    "\n",
    "for node in nodes:\n",
    "    print(node.text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interleaf was a company that built impressive technology and had smart people, but it was ultimately crushed by Moore's Law in the 1990s due to the exponential growth in the power of commodity processors. Despite adding a scripting language and making software for creating documents, it could not keep up with the rapid advancements in hardware.\n",
      "\n",
      "Viaweb, on the other hand, was an application service provider that created a code editor for users to define their own page styles, which were actually Lisp expressions. The company was eventually bought by Yahoo in the summer of 1998. The Viaweb stock became valuable, and the acquisition marked a significant turning point for its founders. The Viaweb logo featured a white \"V\" on a red circle, which later inspired the Y Combinator logo.\n"
     ]
    }
   ],
   "source": [
    "query_engine = index.as_query_engine(include_text=True)\n",
    "\n",
    "response = query_engine.query(\"What happened at Interleaf and Viaweb?\")\n",
    "\n",
    "print(str(response))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loading from an existing Graph\n",
    "\n",
    "If you have an existing graph, we can connect to and use it!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.graph_stores.nebula import NebulaPropertyGraphStore\n",
    "\n",
    "graph_store = NebulaPropertyGraphStore(\n",
    "    space=\"llamaindex_nebula_property_graph\"\n",
    ")\n",
    "\n",
    "from llama_index.core.vector_stores.simple import SimpleVectorStore\n",
    "\n",
    "vec_store = SimpleVectorStore.from_persist_path(\"./data/nebula_vec_store.json\")\n",
    "\n",
    "index = PropertyGraphIndex.from_existing(\n",
    "    property_graph_store=graph_store,\n",
    "    vector_store=vec_store,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From here, we can still insert more documents!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from llama_index.core import Document\n",
    "\n",
    "document = Document(text=\"LlamaIndex is great!\")\n",
    "\n",
    "index.insert(document)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Llamaindex -> Is -> Great\n"
     ]
    }
   ],
   "source": [
    "nodes = index.as_retriever(include_text=False).retrieve(\"LlamaIndex\")\n",
    "\n",
    "print(nodes[0].text)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
